可参考
我这里是从项目代码里总出来的:
1、首先在application/core文件夹下增加MY_Loader.php文件。只要增加这个类就可以,其他操作不变,在视图文件中就可以使用视图继承了。
文件内容如下:
1 _stacks[$this->_current]['extends'] = $tplname; 41 } 42 43 /** 44 * 开始定义一个区块 45 * 46 * @param string $block_name 47 * @param mixed $config 48 * 49 * @access protected 50 */ 51 protected function _block($block_name, $config = null) 52 { 53 $stack =& $this->_stacks[$this->_current]; 54 if (!empty($stack['blocks_stacks'])) 55 { 56 // 如果存在嵌套的 block,则需要记录下嵌套的关系 57 $last = $stack['blocks_stacks'][count($stack['blocks_stacks']) - 1]; 58 $stack['nested_blocks'][] = array($block_name, $last); 59 } 60 $this->_stacks[$this->_current]['blocks_config'][$block_name] = $config; 61 array_push($stack['blocks_stacks'], $block_name); 62 ob_start(); 63 } 64 65 /** 66 * 结束一个区块 67 * 68 * @access protected 69 */ 70 protected function _endblock() 71 { 72 $block_name = array_pop($this->_stacks[$this->_current]['blocks_stacks']); 73 $this->_stacks[$this->_current]['blocks'][$block_name] = ob_get_clean(); 74 echo "%block_{ $block_name}_{ $this->_stacks[$this->_current]['id']}%"; 75 } 76 77 78 /** 79 * 载入一个视图片段 80 * 81 * @param string $element_name 视图名称 82 * @param array $vars 83 * 84 * @access protected 85 */ 86 protected function _element($element_name, array $vars = null) 87 { 88 $file_exists = FALSE; 89 $filename = ''; 90 foreach ($this->_ci_view_paths as $view_file => $cascade) 91 { 92 $filename = $view_file.$element_name.EXT; 93 if ( ! file_exists($filename)) 94 { 95 $file_exists = FALSE; 96 }else{ 97 $file_exists = TRUE;break; 98 } 99 }100 if(!$file_exists){101 show_error('Unable to load the requested file: '.$filename);102 }else{103 extract($this->_ci_cached_vars);104 if (is_array($vars)) extract($vars);105 include($filename);106 }107 }108 109 /**110 * Loader111 *112 * 这个函数用来加载视图或者文件.113 * 这个函数改写 CI_Loader 类内函数,使其支持视图继承和多重继承。114 *115 * @access private116 * @param array117 * @return void118 */119 function _ci_load($_ci_data)120 {121 // 设置默认的数据变量122 foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return', '_ci_viewid', '_ci_stack') as $_ci_val)123 {124 $$_ci_val = ( ! isset($_ci_data[$_ci_val])) ? FALSE : $_ci_data[$_ci_val];125 }126 127 // 设置请求文件的路径128 if ($_ci_path != '')129 {130 $_ci_x = explode('/', $_ci_path);131 $_ci_file = end($_ci_x);132 }133 else134 {135 $_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION);136 $_ci_file = ($_ci_ext == '') ? $_ci_view.'.php' : $_ci_view;137 138 foreach ($this->_ci_view_paths as $view_file => $cascade)139 {140 if (file_exists($view_file.$_ci_file))141 {142 $_ci_path = $view_file.$_ci_file;143 $file_exists = TRUE;144 break;145 }146 147 if ( ! $cascade)148 {149 break;150 }151 }152 }153 154 if ( ! file_exists($_ci_path))155 {156 show_error('Unable to load the requested file: '.$_ci_file);157 }158 159 // 这允许任何加载使用 $this->load (views, files, etc.)160 // 成为从内部控制器和模型函数访问.161 162 $_ci_CI =& get_instance();163 foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var)164 {165 if ( ! isset($this->$_ci_key))166 {167 $this->$_ci_key =& $_ci_CI->$_ci_key;168 }169 }170 171 /*172 * 提取缓存和变量 也就是把数组下标变成变量173 *174 * You can either set variables using the dedicated $this->load_vars()175 * function or via the second parameter of this function. We'll merge176 * the two types and cache them so that views that are embedded within177 * other views can have access to these variables.178 */179 if (is_array($_ci_vars))180 {181 $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars);182 }183 extract($this->_ci_cached_vars);184 185 //-----by:kth007 20100422------------------------------------------------------------------------------186 if ( ! $_ci_viewid) $_ci_viewid = mt_rand();187 188 $stack = array(189 'id' => $_ci_viewid,190 'contents' => '',191 'extends' => '',192 'blocks_stacks' => array(),193 'blocks' => array(),194 'blocks_config' => array(),195 'nested_blocks' => array(),196 );197 array_push($this->_stacks, $stack);198 $this->_current = count($this->_stacks) - 1;199 unset($stack);200 //-----------------------------------------------------------------------------------201 202 /*203 * 缓冲输出204 *205 * We buffer the output for two reasons:206 * 1. Speed. You get a significant speed boost.207 * 2. So that the final rendered template can be208 * post-processed by the output class. Why do we209 * need post processing? For one thing, in order to210 * show the elapsed page load time. Unless we211 * can intercept the content right before it's sent to212 * the browser and then stop the timer it won't be accurate.213 */214 ob_start();215 216 // If the PHP installation does not support short tags we'll217 // do a little string replacement, changing the short tags218 // to standard PHP echo statements.219 220 if ((bool) @ini_get('short_open_tag') === FALSE AND config_item('rewrite_short_tags') == TRUE)221 {222 echo eval('?>'.preg_replace("/;*\s*\?>/", "; ?>", str_replace(' _stacks[$this->_current];234 $stack['contents'] = ob_get_clean();235 236 // 如果有继承视图,则用继承视图中定义的块内容替换当前视图的块内容237 if (is_array($_ci_stack))238 {239 foreach ($_ci_stack['blocks'] as $block_name => $contents)240 {241 if (isset($stack['blocks_config'][$block_name]))242 {243 switch (strtolower($stack['blocks_config'][$block_name]))244 {245 case 'append':246 $stack['blocks'][$block_name] .= $contents;247 break;248 case 'replace':249 default:250 $stack['blocks'][$block_name] = $contents;251 }252 }253 else254 {255 $stack['blocks'][$block_name] = $contents;256 }257 }258 }259 // 如果有嵌套 block,则替换内容260 while (list($child, $parent) = array_pop($stack['nested_blocks']))261 {262 $stack['blocks'][$parent] = str_replace("%block_{ $child}_{ $_ci_viewid}%",263 $stack['blocks'][$child], $stack['blocks'][$parent]);264 unset($stack['blocks'][$child]);265 }266 // 保存对当前视图堆栈的修改267 $this->_stacks[$this->_current] = $stack;268 269 if ($stack['extends'])270 {271 //私有继承.272 $filename = "{ $stack['extends']}".EXT;273 274 return $this->_ci_load(array(275 '_ci_view' => $filename, 276 //'_ci_vars' => $this->_ci_cached_vars,277 '_ci_return' => $_ci_return,278 '_ci_viewid'=>$_ci_viewid, 279 '_ci_stack'=>$this->_stacks[$this->_current],280 ));281 }282 else283 {284 // 最后一个视图一定是没有 extends 的285 $last = array_pop($this->_stacks);286 foreach ($last['blocks'] as $block_name => $contents)287 {288 $last['contents'] = str_replace("%block_{ $block_name}_{ $last['id']}%",289 $contents, $last['contents']);290 }291 $this->_stacks = array();292 293 294 if ($_ci_return === TRUE)295 {296 @ob_end_clean();297 return $last['contents'];298 }299 300 if (ob_get_level() > $this->_ci_ob_level + 1)301 {302 ob_end_flush();303 }304 else305 {306 $_ci_CI->output->append_output($last['contents']);307 @ob_end_clean();308 }309 310 }311 //--------------------------------------------------------------------------------------------312 313 314 // Return the file data if requested315 /* if ($_ci_return === TRUE)316 {317 $buffer = ob_get_contents();318 @ob_end_clean();319 return $buffer;320 }321 */322 /*323 * Flush the buffer... or buff the flusher?324 *325 * In order to permit views to be nested within326 * other views, we need to flush the content back out whenever327 * we are beyond the first level of output buffering so that328 * it can be seen and included properly by the first included329 * template and any subsequent ones. Oy!330 *331 */332 /* if (ob_get_level() > $this->_ci_ob_level + 1)333 {334 ob_end_flush();335 }336 else337 {338 $_ci_CI->output->append_output(ob_get_contents());339 @ob_end_clean();340 }341 */342 343 344 }345 346 }347 348 /* End of file MY_Loader.php */349 /* Location: ./application/core/MY_Loader.php */
2、在视图文件中使用视图继承:
首先可以在视图中增加一些基础的视图文件作为父视图,以供继承使用,如:view/_layouts/default_layout.php
代码可参考如下:
1 2 3 4 5<?php $this->_block('title'); ?>我的被别人继承的<?php $this->_endblock(); ?> 6 7 8 _block('head'); ?> _endblock(); ?> 9 10 11这里是头部12这里是导航13这里是左栏1415 load->_block('content'); ?> load->_endblock(); ?>16 17_block('footer')?> 这里是尾部 _endblick();?>18 19
然后在自已的视图里就可以继承这个视图了
如:
1 //继承父视图 2 _extends('_layouts/default_layout'); ?> 3 // 重写title 4 _block('title'); ?>我自己的title,覆盖父类的title _endblock(); ?> 5 6 //重写head部分,可以引入一些自己的JS和CSS, 7 _block('head'); ?> _endblock(); ?> 8 9 //覆盖父视图中的contents部分,这里就可以自定义自己的内容部分了10 _block('contents'); ?>11 12 1314 23 24 27 28 29 _endblock(); ?>
还可以载入某个视图片段,方法如下:
load->_element('topnews', $topnews);?>